﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNA_Game_Framework
{
	public abstract class Control
	{
        protected bool enabled;
		protected bool hasFocus;
		protected string name;
		protected object parent;
		protected Vector2 relativePosition;
		protected RightClickMenu rightClickMenu;
		protected bool visible;

		public Rectangle Bounds
		{ get { return new Rectangle((int)ScreenPosition.X, (int)ScreenPosition.Y, (int)Size.X, (int)Size.Y); } }

        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

		public bool HasFocus
		{
			get { return hasFocus; }
			set { hasFocus = value; }
		}

		public int Height
		{
			get { return (int)Size.Y; }
		}

		public string Name
		{
			get { return name; }
			set { name = value; }
		}

		public object Parent
		{
			get { return parent; }
			set { parent = value; }
		}

		/// <summary>
		/// Gets or sets the control's position relative to its parent
		/// </summary>
		public Vector2 ParentPosition
		{
			get
			{
				return relativePosition - ((Control)parent).relativePosition;
			}
			set
			{
				relativePosition = value + ((Control)parent).relativePosition;
			}
		}

		public Screen Screen
		{
			get 
			{
				if (parent is Screen)
				{
					return (Screen)parent;
				}
				else
				{
					return ((Control)parent).Screen;
				}
			}
		}

        /// <summary>
        /// Gets the control's position on the screen
        /// </summary>
		public Vector2 ScreenPosition
		{
			get
			{
				if (parent is Screen)
				{
					return relativePosition;
				}
                else if (parent is Container)
                {
                    return ((Control)parent).ScreenPosition + relativePosition;
                }
				else
				{
					return ((Control)parent).ScreenPosition + relativePosition;
				}
			}
		}

		public Container RightClickMenu
		{
			get { return rightClickMenu; }
		}

		public abstract Vector2 Size
		{ get; }

		public bool Visible
		{
			get { return visible; }
			set { visible = value; }
		}

		public int Width
		{
			get { return (int)Size.X; }
		}

		public Container Window
		{
			get
			{
				if (this is Container)
				{
					return (Container)this;
				}
				else
				{
					return ((Control)parent).Window;
				}
			}
		}

		/// <summary>
		/// Gets or sets the position of the control within its container.
		/// </summary>
		public Vector2 WindowPosition
		{
			get { return relativePosition; }
			set { relativePosition = value; }
		}

		public Control(string name, object parent, Vector2 position)
		{
			Name = name;
			Parent = parent;
			WindowPosition = position;

            enabled = true;
			hasFocus = false;
			rightClickMenu = null;
			visible = true;
		}

		protected bool IsWithinBounds(Vector2 position)
		{
			bool isWithinBounds = true;
			if (Bounds.X > position.X || Bounds.X + Bounds.Width < position.X)
			{
				isWithinBounds = false;
			}
			if (Bounds.Y > position.Y || Bounds.Y + Bounds.Height < position.Y)
			{
				isWithinBounds = false;
			}

			return isWithinBounds;
		}

		public void SetRightClickMenu(RightClickMenu rightClickMenu)
		{
			this.rightClickMenu = rightClickMenu;
		}

		internal abstract void Draw(SpriteBatch spriteBatch);

        internal virtual bool OnLeftClick(MouseEventArgs e)
        {
            return false;
        }

		internal virtual bool OnRightClick(MouseEventArgs e)
		{
			if (rightClickMenu != null && IsWithinBounds(e.Position) && Enabled)
			{
				rightClickMenu.WindowPosition = e.Position - new Vector2(10, 10);
				if (rightClickMenu.Enabled)
				{
					rightClickMenu.Visible = true;
				}
				return true;
			}
			return false;
		}

		internal virtual bool OnMouseMoved(MouseEventArgs e)
        {
            return false;
        }

		internal virtual bool OnMouseLeftDragged(MouseEventArgs e)
		{
			return false;
		}
	}
}
